package com.jediflasher.game_server

import com.google.protobuf.Message
import com.jediflasher.game_server.messages.HeaderMessage.{ServiceType, MessageType, Header}
import com.jediflasher.game_server.messages.ServiceMethodLogin.MethodLogin
import com.jediflasher.game_server.messages.RequestMessageLogin.LoginRequest
import com.jediflasher.game_server.messages.ServiceMethodMovement.MethodMovement
import com.jediflasher.game_server.messages.RequestCharacterInfo.CharacterInfoRequest
import com.jediflasher.game_server.messages.RequestCharacterMove.CharacterMoveRequest
import com.jediflasher.game_server.messages.MessageChangeUsers.ChangeUsers
import com.jediflasher.game_server.messages.RequestWorldInfo.WorldInfoRequest
import java.io.DataInputStream

/**
 * User: Obi
 * Date: 31.07.11
 * Time: 20:38
 */

class MessageWrapper {

	private var _header: Header = null;

	/**
	 * id запроса
	 */
	def requestId: Int = _header.getRequestId;

	/**
	 * Тип сервиса
	 */
	def serviceType: ServiceType = _header.getServiceType;

	/**
	 * Тип сообщения
	 */
	def messageType: MessageType = _header.getMessageType;

	/**
	 * Метод сервиса
	 */
	def method: Int = _header.getMethod;

	/**
	 * Десериализованное тело сообщения
	 */
	var message: Message = null;

	/**
	 * Считывает пакет и десереализует сообщения
	 */
	def read(in: DataInputStream): MessageWrapper = {
		val headerSize: Int = in.readInt();

		val headerBytes = new Array[Byte](headerSize);
		in.read(headerBytes, 0, headerSize);

		_header = Header.parseFrom(headerBytes);

		val bodySize: Int = _header.getBodySize;
		if (bodySize > 0) {
			val messageBytes = new Array[Byte](bodySize);
			in.read(messageBytes, 0, bodySize);

			serviceType match {
				case ServiceType.LOGIN => readAsLoginMessage(messageBytes);
				case ServiceType.MOVEMENT => readAsMovementMessage(messageBytes);
			}
		}
		this;
	}

	private def readAsLoginMessage(bytes:Array[Byte]) {
		message = method match {
			case MethodLogin.LOGIN_VALUE => LoginRequest.parseFrom(bytes);
		}
	}

	private def readAsMovementMessage(bytes:Array[Byte]) {
		message = method match {
			case MethodMovement.CHARACTER_INFO_VALUE => CharacterInfoRequest.parseFrom(bytes);
			case MethodMovement.CHARACTER_MOVE_VALUE => CharacterMoveRequest.parseFrom(bytes);
			case MethodMovement.USERS_ADD_VALUE => ChangeUsers.parseFrom(bytes);
			case MethodMovement.USERS_REMOVE_VALUE => ChangeUsers.parseFrom(bytes);
			case MethodMovement.WORLD_INFO_VALUE => WorldInfoRequest.parseFrom(bytes);
		}
	}
}